package main

/*
  by zy, 

  2025.11.06
    检查七牛云指定 <domain> 绑定证书的状态:

    -check -fqdn <domain> [-days <N>]

    输出一个字符串:
      - Pending:  尚未生效
      - Valid:    有效
      - Expiring: 有效，但在过期窗口内，过期窗口可以使用 -days 配置, 默认为 14 天
      - Expired:  已经过期
*/

import (
  "os"
  "fmt"
  "net/http"
)

type HttpsConf struct {
  CertID          string  `json:"certId"`  // 只使用 CertID
  ForceHttps      bool    `json:"forceHttps"`
  Http2Enable     bool    `json:"http2Enable"`
}

type RespDomainConfig struct {
  Code         int       `json:"code"`
  Error        string    `json:"error"`
  ErrorCode    string    `json:"error_code"`
  Https        HttpsConf `json:"https"` // 这个接口返回内容比较多，只留 https 配置，其它忽略
}

func handleCheck(cfg *CLI) {
  // 获取域名使用的证书 ID
  var err error
  cfg.CertID, err = getBindingCertID(cfg)
  if err != nil {
    fmt.Fprintf(os.Stderr, "failed to get binding CertID: %v\n", err)
    os.Exit(ExitOtherError)
  }

  // 下载证书
  cert, err := downloadByCertID(cfg)
  if err != nil {
    fmt.Fprintf(os.Stderr, "fail to download Cert %s: %v\n", cfg.CertID, err)
    os.Exit(ExitOtherError)
  }

  // 输出证书状态
  fmt.Printf("%s\n", cert.CertState(cfg.Days))  
}

// 获取指定 ID 的证书
func downloadByCertID(cfg *CLI) (*Cert, error) {
  resp, err := sendDownloadRequest(cfg)
  if err != nil {
    return nil, fmt.Errorf("failed on download: %s, %w\n", cfg.CertID, err)
  }

  body, err := readRespBody(resp)
  if err != nil {
    return nil, err
  }

  if resp.StatusCode != 200 { // http 状态码非 200 时，返回响应体字符串
    return nil, fmt.Errorf("StatusCode: %d, %s\n", resp.StatusCode, string(body))
  }

  sbody, err := parseJSONResponse[RespBodyDownload](body)
  if err != nil {
    return nil, fmt.Errorf("failed to parse response\n%s\n%w\n", string(body), err) 
  }
  
  cert := sbody.Cert
  return &cert, nil // 不要返回 &sbody.CertID
}

// 获取指定域名绑定的证书 ID
func getBindingCertID(cfg *CLI) (string, error) { // GET /domain/<domain>
  resp, err := sendQiNiuRequest(cfg, http.MethodGet, "/domain/" + cfg.Fqdn, "", nil)
  if err != nil {
     return "", err
  }
  defer resp.Body.Close()

  body, err := readRespBody(resp);
  if err != nil {
    return "", err
  }

  if resp.StatusCode != 200 { // http 状态码非 200 时，返回响应体字符串
    return "", fmt.Errorf("StatusCode: %d, %s\n", resp.StatusCode, string(body))
  }

  dc, err := parseJSONResponse[RespDomainConfig](body) // domain config
  if err != nil {
    return "", fmt.Errorf("failed to parse response\n%s\n%w\n", string(body), err)
  }
 
  if dc.Https.CertID == "" {
    return "", fmt.Errorf("got empty CertID\n")
  }
  return dc.Https.CertID, nil
}
